home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / nt / nrlogind.zip / RLOGIND.C < prev    next >
C/C++ Source or Header  |  1994-02-18  |  8KB  |  312 lines

  1. /*
  2.  * Copyright (C) 1994 Nathaniel W. Mishkin.
  3.  * Copyright (C) 1991 Microsoft Corporation.
  4.  * All rights reserved.
  5.  */
  6.  
  7. #include <windows.h>
  8. #include <winsock.h>
  9.  
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <stdarg.h>
  13. #include <assert.h>
  14. #include <time.h>
  15. #include <stdarg.h>
  16.  
  17. #include "session.h"
  18.  
  19. #define LOGIN_PORT 513
  20. #define HOSTS_EQUIV "hosts.eqv"
  21. #define PERMISSION_DENIED_MSG "Permission denied\n"
  22.  
  23. BOOL DebugFlag = FALSE;
  24. BOOL InsecureFlag = FALSE;
  25.  
  26. // **********************************************************************
  27. // GetStr
  28. //
  29. // Read a string from the socket.  Used as part of rlogin protocol processing.
  30. //
  31.  
  32. static BOOL 
  33. GetStr(
  34.     SOCKET Socket,
  35.     char *buf,
  36.     int cnt
  37. )
  38. {
  39.     char c;
  40.     
  41.     do {
  42.         if (recv(Socket, &c, 1, 0) != 1)
  43.             return(FALSE);
  44.         *buf++ = c;
  45.         if (--cnt == 0) {
  46.             SessionLog(EVENTLOG_ERROR_TYPE, "protocol string too long");
  47.             return(FALSE);
  48.         }
  49.     } while (c != 0);
  50.  
  51.     return(TRUE);
  52. }
  53.  
  54.  
  55. // **********************************************************************
  56. // CtrlHandler
  57. //
  58. // Ctrl-C handler routine.
  59. //
  60.  
  61. static BOOL
  62. CtrlHandler(
  63.     DWORD CtrlType
  64.     )
  65. {
  66.     //
  67.     // We'll handle Ctrl-C events
  68.     //
  69.  
  70.     return (CtrlType == CTRL_C_EVENT);
  71. }
  72.  
  73. // **********************************************************************
  74. // CheckLogin
  75. //
  76. // Make sure the remote user/host is one we want to let in.
  77. //
  78.  
  79. static BOOL
  80. CheckLogin(
  81.     char *RemoteUser,
  82.     char *RemoteHost,
  83.     char *LocalUser,
  84.     u_long ClientAddr
  85. )
  86. {
  87.     struct hostent *HostEnt;
  88.     BYTE HostName[100];
  89.     BOOL HostOk = FALSE;
  90.     FILE *Fp;
  91.     char *LoggedInUser = getenv("USERNAME");
  92.  
  93.     if (strcmp(LocalUser, LoggedInUser) != 0) {
  94.         SessionLog(EVENTLOG_AUDIT_FAILURE, 
  95.                   "Login rejected -- remote user: %s@%s, local user name mismatch (\"%s\" != \"%s\")",
  96.                   RemoteUser, RemoteHost, LocalUser, LoggedInUser);
  97.         return FALSE;
  98.     }
  99.  
  100.     Fp = fopen(HOSTS_EQUIV, "r");
  101.     if (Fp == NULL) {
  102.         SessionLog(EVENTLOG_ERROR_TYPE, "Can't open \"%s\" -- exiting", HOSTS_EQUIV);
  103.         return FALSE;
  104.     }
  105.  
  106.     while (fgets(HostName, sizeof HostName, Fp) != NULL) {
  107.         HostName[strlen(HostName) - 1] = '\0';     // Strip LF
  108.         if ((HostEnt = gethostbyname(HostName)) != NULL) 
  109.             if (ClientAddr == * (u_long *) HostEnt->h_addr) {
  110.                 HostOk = TRUE;
  111.                 break;
  112.             }
  113.     }
  114.  
  115.     fclose(Fp);
  116.  
  117.     if (! HostOk) 
  118.         SessionLog(EVENTLOG_AUDIT_FAILURE, 
  119.                   "Login rejected -- Remote user: %s@%s, illegal host",
  120.                   RemoteUser, RemoteHost);
  121.  
  122.     return HostOk;
  123. }
  124.  
  125. // **********************************************************************
  126. // RloginThreadFn
  127. //
  128. // Thread base function for each concurrent rlogin session.
  129. //
  130.  
  131. VOID
  132. RloginThreadFn(
  133.     PVOID Parameter
  134.     )
  135. {
  136.     SOCKET ClientSocket = (SOCKET) Parameter;
  137.     BYTE LocalUser[16], RemoteUser[16], TerminalType[64];
  138.     struct hostent *HostEnt;
  139.     BYTE HostName[100];
  140.     BYTE Buffer[16];
  141.     struct sockaddr_in ClientSockAddr;
  142.     int ClientLen;
  143.  
  144.     //
  145.     // Get leading null byte
  146.     //
  147.     recv(ClientSocket, (char *) &Buffer, 1, 0);
  148.  
  149.     //
  150.     // Get remote and local user names and terminal type
  151.     //
  152.     GetStr(ClientSocket, RemoteUser, sizeof(RemoteUser));
  153.     GetStr(ClientSocket, LocalUser, sizeof(LocalUser));
  154.     GetStr(ClientSocket, TerminalType, sizeof(TerminalType));
  155.  
  156.     //
  157.     // Get name of peer host
  158.     //
  159.  
  160.     ClientLen = sizeof (ClientSockAddr);
  161.     if (getpeername(ClientSocket, (struct sockaddr *) &ClientSockAddr, &ClientLen) != 0) {
  162.         SessionLog(EVENTLOG_ERROR_TYPE, "getpeername: %d", WSAGetLastError());
  163.         return;
  164.     }
  165.  
  166.     if ((HostEnt = gethostbyaddr((char *) &ClientSockAddr.sin_addr, 
  167.                                  sizeof ClientSockAddr.sin_addr, PF_INET)) == NULL) 
  168.     {
  169.         sprintf(HostName, inet_ntoa(ClientSockAddr.sin_addr));
  170.     }
  171.     else {
  172.         strcpy(HostName, HostEnt->h_name);
  173.     }
  174.  
  175.     send(ClientSocket, "", 1, 0);
  176.  
  177.     if (! InsecureFlag && 
  178.         ! CheckLogin(RemoteUser, HostName, 
  179.                      LocalUser[0] == '\0' ? RemoteUser : LocalUser,
  180.                      ClientSockAddr.sin_addr.s_addr))
  181.     {
  182.         send(ClientSocket, PERMISSION_DENIED_MSG, sizeof PERMISSION_DENIED_MSG, 0);
  183.         closesocket(ClientSocket);
  184.         return;
  185.     }
  186.  
  187.     SessionLog(EVENTLOG_AUDIT_SUCCESS, "LOGIN  -- remote user: %s@%s, local user: %s",
  188.                RemoteUser, HostName, LocalUser);
  189.  
  190.     //
  191.     // Do the real work of running the connection.
  192.     //
  193.     if (! SessionRun(ClientSocket)) {
  194.         SessionLog(EVENTLOG_ERROR_TYPE, "SessionRun: %d", GetLastError());
  195.         return;
  196.     }
  197.  
  198.     SessionLog(EVENTLOG_AUDIT_SUCCESS, "LOGOUT  -- remote user: %s@%s, local user: %s",
  199.                RemoteUser, HostName, LocalUser);
  200.  
  201.     ExitThread(0);
  202. }
  203.  
  204.  
  205. // **********************************************************************
  206. // main
  207. //
  208. // Main program
  209. //
  210.  
  211. VOID
  212. main(
  213.     int argc,
  214.     char *argv[]
  215. )
  216. {
  217.     SOCKET AcceptSocket, ClientSocket;
  218.     struct sockaddr_in FromSockAddr, SockAddr;
  219.     int FromLen;
  220.     int Err;
  221.     WSADATA WsaData;
  222.     SECURITY_ATTRIBUTES SecurityAttributes;
  223.     HANDLE ThreadHandle;
  224.     DWORD ThreadId;
  225.     char *p;
  226.  
  227.     if (argc > 1 && argv[1][0] == '-') 
  228.         for (p = &argv[1][1]; *p != '\0'; p++)
  229.             switch (*p) {
  230.                 case 'i':
  231.                     InsecureFlag = TRUE;
  232.                     break;
  233.  
  234.                 case 'd':
  235.                     DebugFlag = TRUE;
  236.                     break;
  237.  
  238.                 default:
  239.                     SessionLog(EVENTLOG_ERROR_TYPE, "Unrecognized option: %c", *p);
  240.                     exit(1);
  241.             }
  242.  
  243.     if ((Err = WSAStartup(MAKEWORD(1, 1), &WsaData)) != 0) {
  244.         SessionLog(EVENTLOG_ERROR_TYPE, "WSAStartup: %d", Err);
  245.         return;
  246.     }
  247.     
  248.     //
  249.     // Install a handler for Ctrl-C
  250.     //
  251.     if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE) &CtrlHandler, TRUE)) {
  252.         SessionLog(EVENTLOG_ERROR_TYPE, 
  253.             "Failed to install control-C handler, error = %d\n", GetLastError());
  254.         return;
  255.     }
  256.  
  257.     //
  258.     // Setup a socket to listen on
  259.     //
  260.  
  261.     if ((AcceptSocket = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
  262.         SessionLog(EVENTLOG_ERROR_TYPE, "socket: %d\n", WSAGetLastError());
  263.         return;
  264.     }
  265.     
  266.     SockAddr.sin_family = PF_INET;
  267.     SockAddr.sin_port = htons(LOGIN_PORT);
  268.     SockAddr.sin_addr.s_addr = 0;
  269.  
  270.     if (bind(AcceptSocket, (struct sockaddr *) &SockAddr, sizeof(SockAddr)) != 0) {
  271.         SessionLog(EVENTLOG_ERROR_TYPE, "bind: %d", WSAGetLastError());
  272.         return;
  273.     }
  274.  
  275.     if (listen(AcceptSocket, 1) != 0) {
  276.         SessionLog(EVENTLOG_ERROR_TYPE, "listen: %d", WSAGetLastError());
  277.         return;
  278.     }
  279.  
  280.     SecurityAttributes.nLength = sizeof(SecurityAttributes);
  281.     SecurityAttributes.lpSecurityDescriptor = NULL; // Use default ACL
  282.     SecurityAttributes.bInheritHandle = FALSE; // No inheritance
  283.  
  284.     //
  285.     // Loop forever, waiting for incoming connections.
  286.     //
  287.  
  288.     SessionLog(EVENTLOG_AUDIT_SUCCESS, "Waiting for incoming connections...");
  289.  
  290.     while (TRUE) {
  291.         FromLen = sizeof (FromSockAddr);
  292.         if ((ClientSocket = accept(AcceptSocket, (struct sockaddr *) &FromSockAddr, &FromLen)) == 
  293.             INVALID_SOCKET) 
  294.             {
  295.                 SessionLog(EVENTLOG_ERROR_TYPE, "accept: %d", WSAGetLastError());
  296.                 return;
  297.             }
  298.         
  299.         ThreadHandle = 
  300.             CreateThread(&SecurityAttributes, 0, 
  301.                          (LPTHREAD_START_ROUTINE) RloginThreadFn,
  302.                          (LPVOID) ClientSocket, 0, &ThreadId);
  303.         if (ThreadHandle == NULL) {
  304.             SessionLog(EVENTLOG_ERROR_TYPE, "CreateThread: %d", GetLastError());
  305.             continue;
  306.         }
  307.  
  308.         CloseHandle(ThreadHandle);
  309.     }
  310. }
  311.  
  312.